# 基于PyTorch的房价线性回归预测

import pandas as pd
import torch
data=pd.read_excel('./Real estate valuation data set.xlsx')

# print(data.head(5))

col_name=data.keys()
# print("数据处理之前的列名称",col_name)
# 对便利店的数量做one-hot编码处理
data=pd.get_dummies(data,columns=['X4 number of convenience stores'])
col_name=data.keys()
# print('数据处理之后的列名称',col_name)
x=data[['X1 transaction date', 'X2 house age',
        'X3 distance to the nearest MRT station',
        'X5 latitude',
        'X6 longitude',
        'X4 number of convenience stores_0',
        'X4 number of convenience stores_1',
        'X4 number of convenience stores_2',
        'X4 number of convenience stores_3',
        'X4 number of convenience stores_4',
        'X4 number of convenience stores_5',
        'X4 number of convenience stores_6',
        'X4 number of convenience stores_7',
        'X4 number of convenience stores_8',
        'X4 number of convenience stores_9',
        'X4 number of convenience stores_10']]
y = data['Y house price of unit area']
'''
变量名称           角色  类型  人口  描述                                      单位          缺失值
---------------------------------------------------------------------------------------------
序号               编号  整数      -                                        -             无
X1交易日期         特征  连续的    例如,2013.250=2013年3月、2013.500=2013年6月等。  -             无
X2房龄             特征  连续的    -                                        年            无
X3到最近的地铁站的距离 特征 连续的    -                                        米            无
X4便利店数量        特征  整数      步行生活圈内便利店数量                          整数          无
X5纬度             特征  连续的    地理坐标、纬度                                度            无
X6经度             特征  连续的    地理坐标、经度                                度            无
Y户房单位面积价格   目标  连续的    10000新台币/平,其中Ping是本地单位,1平方=3.3平方米 10000新台币/平价 无
'''
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

print(x_train)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_train_scaler = scaler.fit_transform(x_train)
x_test_scaler = scaler.transform(x_test)
# print(x_train_scaler)
# print(x_test_scaler)
x_train_tensor = torch.tensor(x_train_scaler, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)
x_test_tensor = torch.tensor(x_test_scaler, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1)

import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
#导入TensorboardX 中的SummaryWriter
from tensorboardX import SummaryWriter
#创建SummaryWriter的对象
writer=SummaryWriter(logdir="logs")
# 可视化一个神经网络
model = nn.Sequential(nn.Linear(x_train_tensor.shape[1],1))
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(),lr=0.1)

epochs = 1000
for epochs in range(1, epochs+1):
        output = model(x_train_tensor)
        loss = criterion(output, y_train_tensor)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        writer.add_scalar("loss", loss, epochs)
        writer.add_scalar("learing_rate", optimizer.param_groups[0]["lr"], epochs)
        print(f'训练集损失：{loss.item()}')
        print(f'迭代次数:{epochs}')
writer.add_graph(model,torch.rand(16,))
writer.close()
# python -m tensorboard.main --logdir="./logs"

model.eval()
with torch.no_grad():
        pre = model(x_test_tensor)
        test_loss = criterion(pre, y_test_tensor)
        print(f'测试集损失：{test_loss}')



pre_numpy = pre.detach().cpu().numpy()
y_test_numpy = y_test_tensor.detach().cpu().numpy()

plt.figure(0)
plt.scatter(y_test_numpy, pre_numpy, color = 'yellow')
plt.plot([min(y_test_numpy), max(y_test_numpy)], [min(y_test_numpy), max(y_test_numpy)], color='blue', linewidth=2)
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title('Regression results')

plt.figure(1)
sorted_indices = x_test.index.argsort()
y_test_sorted = y_test.iloc[sorted_indices]
y_pred_sorted = pd.Series(pre_numpy.squeeze()).iloc[sorted_indices]
plt.plot(y_test_sorted.values, label='Acatual Values', marker='o')
plt.plot(y_pred_sorted.values, label='Predicted Values', marker='*')
plt.xlabel('Sorted Index')
plt.ylabel('Values')
plt.title('Actual vs Predicted Values in Linear Regression')

plt.show()













